package com.xinqi.modules.databank.v2.service.common.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.response.R;
import com.xinqi.common.core.enums.ClassRoleEnum;
import com.xinqi.common.core.enums.CourseContentTypeEnum;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.satoken.utils.LoginHelper;
import com.xinqi.common.base.dto.CommonFileDTO;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.mybatis.utils.Pages;
import com.xinqi.modules.course.clazz.client.ClassStudentClient;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentResultDTO;
import com.xinqi.modules.databank.dto.req.CourseResourceUpdateDTO;
import com.xinqi.modules.databank.dto.req.DownloadDTO;
import com.xinqi.modules.databank.dto.req.ResourceBaseQueryDTO;
import com.xinqi.modules.databank.dto.rsp.CourseResourceBaseResultDTO;
import com.xinqi.modules.databank.v2.convert.CourseResourceConvert;
import com.xinqi.modules.databank.v2.domain.CourseResourceEntity;
import com.xinqi.modules.databank.v2.manager.CourseResourceBaseManager;
import com.xinqi.modules.databank.v2.service.common.CourseResourceBaseService;
import com.xinqi.modules.databank.v2.service.common.CourseContentService;
import com.xinqi.modules.databank.v2.service.resource.CourseResourceDataService;
import com.xinqi.modules.databank.v2.service.student.ResourceStudentLogService;
import com.xinqi.modules.databank.v2.service.video.CourseResourceVideoService;
import groovy.lang.Lazy;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 资料库公共方法
 * @author dzy
 */

@Service
@RequiredArgsConstructor
public class CourseResourceBaseServiceImpl implements CourseResourceBaseService {

    private final CourseResourceConvert courseResourceConvert;
    private final CourseResourceBaseManager courseResourceBaseManager;

    private final ClassStudentClient classStudentClient;

    @Lazy
    private final CourseContentService courseContentService;

    private final CourseResourceDataService resourceDataService;

    private final CourseResourceVideoService resourceVideoService;

    private final ResourceStudentLogService resourceStudentLogService;

    /**
     * 老师端查询已发布互动课件
     * @Author dzy
     * @Date 15:02 2023/3/16
     * @Return
     * @Exception
     */
    @Override
    @DS("slaver")
    public PageInfo<CourseResourceBaseResultDTO> teacherReleasePage(ResourceBaseQueryDTO query) {
        IPage<CourseResourceBaseResultDTO> page = getPage(query);
        page = courseResourceBaseManager.teacherReleasePageList(page, query);
        PageInfo<CourseResourceBaseResultDTO> pageInfo = Pages.convert(page);
        return pageInfo;
    }

    /**
     * 老师端查询未发布互动课件
     * @Author dzy
     * @Date 2023/07/14
     * @Return
     * @Exception
     */
    @Override
    @DS("slaver")
    public PageInfo<CourseResourceBaseResultDTO> teacherUnreleasePage(ResourceBaseQueryDTO query) {
        IPage<CourseResourceBaseResultDTO> page = getPage(query);
        page = courseResourceBaseManager.teacherPageList(page, query);
        PageInfo<CourseResourceBaseResultDTO> pageInfo = Pages.convert(page);
        return pageInfo;
    }

    /**
     * 学生查询互动课件
     * @Author dzy
     * @Date 2023/07/14
     * @Description
     * @Return
     * @Exception
     */
    @Override
    @DS("slaver")
    public PageInfo<CourseResourceBaseResultDTO> studentPage(ResourceBaseQueryDTO query) {

        // 获取主学生信息
        Long userId = LoginHelper.getUserId();
        ClassStudentResultDTO student = R.as(classStudentClient.findVirtualClassStudentByClassIdAndUserId(query.getClassId(), userId));

        query.setUserId(student.getStudentId());
        IPage<CourseResourceBaseResultDTO> page = getPage(query);
        page = courseResourceBaseManager.pageList(page, query);
        PageInfo<CourseResourceBaseResultDTO> pageInfo = Pages.convert(page);
        return pageInfo;
    }

    /**
     * 分页数据转换
     * @author dzy
     */
    private IPage<CourseResourceBaseResultDTO> getPage(ResourceBaseQueryDTO queryDTO) {
        IPage<CourseResourceBaseResultDTO> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        return page;
    }

    /**
     * 记录学生端下载资料库文件次数
     * @param downloadDto 下载实体集合
     * @return  List<String> 返回地址集合
     */
    @Override
    public List<String> getDownPaths(DownloadDTO downloadDto) {
        List<String> urls = new ArrayList<>();
        if (Objects.nonNull(downloadDto) && CollectionUtils.isNotEmpty(downloadDto.getIds())
            && downloadDto.getIds().size() > 0) {
            List<CourseResourceEntity> entityList = courseResourceBaseManager.selectBatchIds(downloadDto.getIds());
            if (Objects.nonNull(entityList) && entityList.size() > 0) {
                for (CourseResourceEntity entity : entityList) {
                    //获取文本文件
                    if (StringUtils.isNotEmpty(entity.getFileurls())) {
                        List<CommonFileDTO> fileDTOS = JSON.parseArray(entity.getFileurls(), CommonFileDTO.class);
                        if (Objects.nonNull(fileDTOS) && fileDTOS.size() > 0) {
                            for (CommonFileDTO fileDTO : fileDTOS) {
                                urls.add(fileDTO.getFileUrl());
                            }
                        }
                    }
                    //获取图片
                    if (StringUtils.isNotEmpty(entity.getImages())) {
                        List<CommonFileDTO> imageDtos = JSON.parseArray(entity.getImages(), CommonFileDTO.class);
                        if (Objects.nonNull(imageDtos) && imageDtos.size() > 0) {
                            for (CommonFileDTO imageDto : imageDtos) {
                                urls.add(imageDto.getUrl());
                            }
                        }
                    }
                }
            }
        }
        return urls;
    }

    /**
     * 获取资料库数据
     * @author dzy
     */
    @Override
    public CourseResourceBaseResultDTO findById(Long id) {
        return courseResourceConvert.convert(courseResourceBaseManager.getById(id));
    }

    /**
     * 修改资料信息
     * @author dzy
     */
    @Override
    public Boolean update(CourseResourceUpdateDTO dto) {
        return courseResourceBaseManager.updateById(courseResourceConvert.update(dto));
    }

    /**
     * 单个删除资料库数据
     * @author dzy
     */
    @Override
    public boolean deletedById(Long id) {
        boolean flag = courseResourceBaseManager.deleteById(id);
        if (flag) {
            courseContentService.deletedById(id);
        }
        return flag;
    }

    /**
     * 批量删除资料库数据
     * @author dzy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletedByIds(List<Long> ids) {

        // 校验是否有删除集合
        CommonErrors.BAD_REQUEST.check(CollectionUtils.isNotEmpty(ids), MessageUtils.message("common.remove.param.not.blank"));

        // 判断是否数据存在(获取其中一条数据)
        CourseResourceEntity entity = Optional.ofNullable(courseResourceBaseManager.getById(ids.get(0).longValue()))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException("数据不存在"));

        // 校验权限
        List<ClassRoleEnum> classRoles = new ArrayList<>();
        classRoles.add(ClassRoleEnum.TEACHER);
        classRoles.add(ClassRoleEnum.ASSISTANT);
        classStudentClient.checkRole(entity.getClassId(), LoginHelper.getUserId(), classRoles);

        // 删除资料库数据
        boolean flag = courseResourceBaseManager.deletedByIds(ids);

        // 删除课程内容汇总数据
        courseContentService.deletedByIds(ids);

        return flag;
    }

    /**
     * 定时发布资料库
     * @author dzy
     */
    @Override
    public boolean scheduleResourceCourse() {
        LambdaQueryWrapper<CourseResourceEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseResourceEntity::getTiming, YesNoNumberEnum.YES.getCode());
        wrapper.eq(CourseResourceEntity::getStatus, YesNoNumberEnum.NO.getCode());
        wrapper.le(CourseResourceEntity::getReleaseTime, LocalDateTime.now());
        wrapper.orderByAsc(CourseResourceEntity::getReleaseTime);
        wrapper.last("limit 500");
        List<CourseResourceEntity> entities = courseResourceBaseManager.list(wrapper);
        if (entities != null && entities.size() > 0) {
            for (CourseResourceEntity entity : entities) {
                if (Objects.equals(CourseContentTypeEnum.DATA.getCode(), entity.getContentType())) {
                    resourceDataService.timingPublish(entity);
                } else if (Objects.equals(CourseContentTypeEnum.INTERACTIVE_VIDEO.getCode(), entity.getContentType())) {
                    resourceVideoService.timingPublish(entity);
                }

            }
        }
        return true;
    }

    /**
     * 加入班级同步资料库数据
     * @author dzy
     */
    @Override
    public boolean joinClassSyncResource(Long classId, Long studentId) {
        LambdaQueryWrapper<CourseResourceEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseResourceEntity::getStatus, YesNoNumberEnum.NO.getCode());
        wrapper.le(CourseResourceEntity::getEndTime, LocalDateTime.now());
        wrapper.orderByAsc(CourseResourceEntity::getReleaseTime);
        List<CourseResourceEntity> entities = courseResourceBaseManager.list(wrapper);
        if (entities != null && entities.size() > 0) {
            for (CourseResourceEntity entity : entities) {
                resourceStudentLogService.syncStudentLogByStudentId(entity, studentId);
            }
        }
        return true;
    }

}
